#include<iostream>
#include<pthread.h>
#include<string>

using namespace std;

#define TNUM 4
typedef void(*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);
bool quit=false;

class ThreadData
{
public:
    ThreadData(string& name,func_t func,pthread_mutex_t* mutex,pthread_cond_t* cond)
    :_name(name)
    ,_func(func)
    ,_mutex(mutex)
    ,_cond(cond)
    {

    }
public:
    string _name;
    func_t _func;
    pthread_mutex_t* _mutex;
    pthread_cond_t* _cond;
}

void func1(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        cout<<"thread -- 下载"<<endl;
        pthread_mutex_unlock(mutex);
    }
}
void func2(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        if(quit)
        {
            cout<<"thread -- 打印"<<endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void func3(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        if(!quit)
        {
            cout<<"thread -- 刷新"<<endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void func4(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mutex);
        pthread_cond_wait(cond,mutex);
        if(!quit)
        {
            cout<<"thread -- 读取用户信息"<<endl;
        }
        pthread_mutex_unlock(mutex);
    }
}
void* Entry(void* args)
{
    ThreadData* td=(ThreadData*)args;
    td->_func(td->_name,td->_mutex,td->_cond);
    delete td;
    return nullptr;
}
int main()
{
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    pthread_mutex_init(&mutex,nullptr);
    pthread_cond_init(&cond,nullptr);
    pthread_t tid[TNUM];
    func_t funcs[TNUM]={func1,func2,func3,func4};
    for(int i=0;i<TNUM;i++)
    {
        string name="thread";
        name+=to_string(i+1);
        ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
        pthread_create(tid+i,nullptr,Entry,(void*)td);
    }
    sleep(2);
    int cnt=10;
    while(cnt)
    {
        pthread_cond_signal(&cond,&mutex);
        cout<<"thread signal"<<cnt--<<endl;
        sleep(1);
    }
    quit=true;
    pthread_cond_broadcast(&cond);
    for(int i=0;i<TNUM;i++)
    {
        pthread_join(tid[i],nullptr);
    }
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}